import { ReviveRuleMap } from "./revive";


export interface RuleInfoParam {
    id: string;
    paramType: string;
    descEn: string;
    descCn: string;
}

export interface RuleInfo {
    id: keyof ReviveRuleMap;
    name: string;
    descEn: string;
    descCn: string;
    paramList?: RuleInfoParam[];
    demoValue?: unknown[];
    checkParam?: (val: unknown[]) => string;
}

export const AllRuleInfoList: RuleInfo[] = [
    {
        id: "add-constant",
        name: "增加常量定义",
        descEn: "Suggests using constant for magic numbers and string literals.",
        descCn: "建议使用常量魔术数字和字符串字面量。",
        paramList: [
            {
                id: "maxLitCount",
                paramType: "字符串(整数)",
                descCn: "警告前允许的字符串字面量的最大实例数",
                descEn: "maximum number of instances of a string literal that are tolerated before warn.",
            },
            {
                id: "allowStr",
                paramType: "字符串",
                descCn: "允许的字符串字面量的逗号分隔列表",
                descEn: "comma-separated list of allowed string literals",
            },
            {
                id: "allowInts",
                paramType: "字符串",
                descCn: "允许的整数的逗号分隔列表",
                descEn: "comma-separated list of allowed integers",
            },
            {
                id: "allowFloats",
                paramType: "字符串",
                descCn: "允许浮点数的逗号分隔列表",
                descEn: "comma-separated list of allowed floats",
            },
            {
                id: "ignoreFuncs",
                paramType: "字符串",
                descCn: "要排除的逗号分隔的函数名列表(支持正则表达式)",
                descEn: "comma-separated list of function names regexp patterns to exclude",
            }
        ],
        demoValue: [{ maxLitCount: "3", allowStrs: "\"\"", allowInts: "0,1,2", allowFloats: "0.0,0.,1.0,1.,2.0,2." }],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个对象元素";
            }
            if (typeof val[0] !== "object") {
                return "参数不是对象元素";
            }

            const obj = val[0] as Object;
            let hasMaxLitCount = false;
            let hasAllowStrs = false;
            let hasAllowInts = false;
            let hasAllowFloats = false;
            let errMsg = "";
            Object.keys(obj).forEach(objKey => {
                if (objKey == "maxLitCount") {
                    hasMaxLitCount = true;
                    if (typeof (obj as any).maxLitCount !== "string") {
                        errMsg = "maxLitCount必须是整数字符串";
                    } else {
                        if (/^[-+]*\d+$/.test((obj as any).maxLitCount)) {
                            const value = parseInt((obj as any).maxLitCount);
                            if (value <= 2) {
                                errMsg = "maxLitCount值必须大于等于2";
                            }
                        } else {
                            errMsg = "maxLitCount必须是整数字符串";
                        }

                    }
                } else if (objKey == "allowStrs") {
                    hasAllowStrs = true;
                    if (typeof (obj as any).allowStrs !== "string") {
                        errMsg = "allowStrs必须是字符串";
                    }
                } else if (objKey == "allowInts") {
                    hasAllowInts = true;
                    if (typeof (obj as any).allowInts !== "string") {
                        errMsg = "allowInts必须是字符串";
                    } else {
                        ((obj as any).allowInts as string).split(",").forEach(partStr => {
                            if (partStr != "" && /^[-+]*\d+$/.test(partStr) == false) {
                                errMsg = `allowInts中${partStr}不是整数`;
                            }
                        })
                    }
                } else if (objKey == "allowFloats") {
                    hasAllowFloats = true;
                    hasAllowInts = true;
                    if (typeof (obj as any).allowFloats !== "string") {
                        errMsg = "allowFloats必须是字符串";
                    } else {
                        ((obj as any).allowFloats as string).split(",").forEach(partStr => {
                            if (partStr != "" && /^[-+]*\d+\.\d*$/.test(partStr) == false) {
                                errMsg = `allowFloats中${partStr}不是浮点数`;
                            }
                        })
                    }
                } else {
                    errMsg = `未知属性${objKey}`;
                }
            });
            if (errMsg != "") {
                return errMsg;
            }
            if (!hasMaxLitCount) {
                return "maxLitCount属性不存在";
            }
            if (!hasAllowStrs) {
                return "allowStrs属性不存在";
            }
            if (!hasAllowInts) {
                return "allowInts属性不存在";
            }
            if (!hasAllowFloats) {
                return "allowFloats属性不存在";
            }
            return "";
        },
    },
    {
        id: "argument-limit",
        name: "参数数量限制",
        descEn: "Warns when a function receives more parameters than the maximum set by the rule's configuration. Enforcing a maximum number of parameters helps to keep the code readable and maintainable.",
        descCn: "当函数接收到的参数超过规则配置设置的最大值时发出警告。强制最大参数数量有助于保持代码的可读性和可维护性。",
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "每个函数允许的最大参数数量。",
                descEn: "the maximum number of parameters allowed per function.",
            }
        ],
        demoValue: [4],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 2) {
                    return "数值不能小于2";
                }
            }
            return "";
        },
    },
    {
        id: "atomic",
        name: "sync/atomic检查",
        descEn: "Check for commonly mistaken usages of the sync/atomic package",
        descCn: "检查sync/atomic包的常见错误用法",
    },
    {
        id: "bare-return",
        name: "直接返回检查",
        descEn: "Warns on bare (a.k.a. naked) returns",
        descCn: "函数直接返回时发出警告",
    },
    {
        id: "banned-characters",
        name: "禁用字符检查",
        descEn: "Checks given banned characters in identifiers(func, var, const). Comments are not checked.",
        descCn: "检查标识符(func, var, const)中给定的禁止字符。",
        paramList: [
            {
                id: "",
                paramType: "单个字符",
                descCn: "禁止的字符",
                descEn: "the characters to ban.",
            }
        ],
        demoValue: ["Ω", "Σ", "σ"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组不能为空";
            }
            let errMsg = "";
            val.forEach(item => {
                if (typeof item !== "string") {
                    errMsg = `${item}不是字符串`;
                } else {
                    if (item.length != 1) {
                        errMsg = "数组元素必须是字符";
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "blank-imports",
        name: "空引用检查",
        descEn: "Blank import should be only in a main or test package, or have a comment justifying it.",
        descCn: "空引用应该只在main或test包中，或者有注释来证明它。",
    },
    {
        id: "bool-literal-in-expr",
        name: "逻辑表达式布尔变量检查",
        descCn: "在逻辑表达式中使用布尔字面量(true, false)可能会降低代码的可读性。该规则建议从逻辑表达式中删除布尔字面值。",
        descEn: "Using Boolean literals (true, false) in logic expressions may make the code less readable. This rule suggests removing Boolean literals from logic expressions.",
    },
    {
        id: "call-to-gc",
        name: "显式垃圾收集调用检查",
        descCn: "除了在基准测试中的特定用途外，显式地调用垃圾收集器是非常可疑的。",
        descEn: "Explicitly invoking the garbage collector is, except for specific uses in benchmarking, very dubious.",
    },
    {
        id: "cognitive-complexity",
        name: "认知复杂度检查",
        descCn: "认知复杂性是衡量代码理解难度的一个指标。圈复杂度很好地度量了代码的“可测试性”，而认知复杂度旨在提供更精确地度量理解代码的难度。强制每个函数的最大复杂度有助于保持代码的可读性和可维护性",
        descEn: `Cognitive complexity is a measure of how hard code is to understand. While cyclomatic complexity is good to measure "testability" of the code, cognitive complexity aims to provide a more precise measure of the difficulty of understanding the code. Enforcing a maximum complexity per function helps to keep code readable and maintainable.`,
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "最大函数复杂度",
                descEn: "the maximum function complexity",
            }
        ],
        demoValue: [7],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 2) {
                    return "数值不能小于2";
                }
            }
            return "";
        },
    },
    {
        id: "comment-spacings",
        name: "注释空格检查",
        descCn: "检查//和句子开头之间的空格",
        descEn: "check space between // and the start of the sentence",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: "例如，接受无空格注释名称",
                descEn: "list of exceptions. For example, to accept comments of the form",
            }
        ],
        demoValue: ["mypragma", "otherpragma"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组不能为空";
            } else {
                let errMsg = "";
                val.forEach(item => {
                    if (typeof item != "string") {
                        errMsg = "数组元素必须是字符串";
                    } else {
                        if (item.trim() == "") {
                            errMsg = "数组元素不能是空字符串"
                        }
                    }
                });
                if (errMsg != "") {
                    return errMsg;
                }
            }
            return "";
        },
    },
    {
        id: "confusing-naming",
        name: "易误解的命名",
        descCn: "结构体的方法或字段的名称只有大小写不同可能会令人困惑",
        descEn: "Methods or fields of struct that have names different only by capitalization could be confusing.",
    },
    {
        id: "confusing-results",
        name: "易误解返回参数检查",
        descCn: "函数返回多个未命名相同类型的结果会造成代码阅读困难",
        descEn: "Function or methods that return multiple, no named, values of the same type could induce error.",
    },
    {
        id: "constant-logical-expr",
        name: "表达式结果恒定检查",
        descCn: "该规则指出计算始终为相同值的逻辑表达式。",
        descEn: "The rule spots logical expressions that evaluate always to the same value.",
    },
    {
        id: "context-as-argument",
        name: "context参数检查",
        descCn: "根据惯例，context.Context应该是函数的第一个参数。该规则指出不遵循约定的函数声明。",
        descEn: "By convention, context.Context should be the first parameter of a function. This rule spots function declarations that do not follow the convention.",
        paramList: [
            {
                id: "allowTypesBefore",
                paramType: "字符串",
                descCn: "逗号分隔的类型列表，可以在'context.Context'之前。",
                descEn: "comma-separated list of types that may be before 'context.Context'",
            }
        ],
        demoValue: [{ allowTypesBefore: "*testing.T,*github.com/user/repo/testing.Harness" }],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个对象元素";
            }
            if (typeof val[0] !== "object") {
                return "参数不是对象元素";
            }
            const obj = val[0] as Object;
            let hasAllowTypesBefore = false;
            let errMsg = "";
            Object.keys(obj).forEach(objKey => {
                if (objKey == "allowTypesBefore") {
                    hasAllowTypesBefore = true;
                    if (typeof (obj as any).allowTypesBefore !== "string") {
                        errMsg = "allowTypesBefore必须是字符串";
                    } else {
                        if (((obj as any).allowTypesBefore as string).trim() == "") {
                            errMsg = "allowTypesBefore值不能是空字符串";
                        }
                    }
                } else {
                    errMsg = `未知属性${objKey}`;
                }
            });
            if (errMsg != "") {
                return errMsg;
            }
            if (!hasAllowTypesBefore) {
                return "allowTypesBefore属性不存在";
            }
            return "";
        },
    },
    {
        id: "context-keys-type",
        name: "context键检查",
        descCn: "基本类型不应该在context.WithValue中用作键。",
        descEn: "Basic types should not be used as a key in context.WithValue.",
    },
    {
        id: "cyclomatic",
        name: "圈复杂度检查",
        descCn: "圈复杂度是代码复杂度的度量。强制每个函数的最大复杂度有助于保持代码的可读性和可维护性。",
        descEn: `Cyclomatic complexity is a measure of code complexity. Enforcing a maximum complexity per function helps to keep code readable and maintainable.`,
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "最大函数复杂度",
                descEn: "the maximum function complexity",
            }
        ],
        demoValue: [3],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 2) {
                    return "数值不能小于2";
                }
            }
            return "";
        },
    },
    {
        id: "datarace",
        name: "数据竞争检查",
        descCn: "该规则指出由go-routine捕获(通过引用)创建go-routine的函数的特定标识符引起的潜在数据竞争。该规则能够发现其中的两种情况:go-routines捕获命名的返回值，以及捕获for-range值。",
        descEn: "This rule spots potential dataraces caused by go-routines capturing (by-reference) particular identifiers of the function from which go-routines are created. The rule is able to spot two of such cases: go-routines capturing named return values, and capturing for-range values.",
    },
    {
        id: "deep-exit",
        name: "退出函数检查",
        descCn: "暴露可以通过退出而停止程序执行的函数的包很难重用。该规则在main()或init()之外的函数中查找程序退出调用。",
        descEn: "Packages exposing functions that can stop program execution by exiting are hard to reuse. This rule looks for program exits in functions other than main() or init().",
    },
    {
        id: "defer",
        name: "defer常见错误检查",
        descCn: "当使用defer语句时，该规则警告一些常见错误",
        descEn: "This rule warns on some common mistakes when using defer statement",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: `它目前会在以下情况下发出警报:
call-chain 即使延迟foo()()形式的调用链是有效的，它也无助于代码理解(只有最后一个调用被延迟)
loop 在循环内部延迟可能会产生误导(延迟的函数不是在循环迭代的末尾执行，而是在当前函数的末尾执行)，并且可能会耗尽执行堆栈
method-call 如果方法没有指针接收器，则延迟对方法的调用可能会导致微妙的错误
recover 在延迟函数外调用recover没有效果
immediate-recover 在注册延迟时调用recover，而不是作为延迟回调的一部分。例如，defer recover()或等效的。
return 从延迟函数中返回值没有任何影响`,
                descEn: `It currently alerts on the following situations:
call-chain even if deferring call-chains of the form foo()() is valid, it does not helps code understanding (only the last call is deferred) 
loop deferring inside loops can be misleading (deferred functions are not executed at the end of the loop iteration but of the current function) and it could lead to exhausting the execution stack
method-call deferring a call to a method can lead to subtle bugs if the method does not have a pointer receiver
recover calling recover outside a deferred function has no effect
immediate-recover calling recover at the time a defer is registered, rather than as part of the deferred callback. e.g. defer recover() or equivalent.
return returning values form a deferred function has no effect
                `,
            }
        ],
        demoValue: [["call-chain", "loop"]],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个字符串数组";
            }
            if (!Array.isArray(val[0])) {
                return "数组元素非字符串数组";
            }
            if ((val[0] as unknown[]).length == 0) {
                return "字符串数组为空";
            }
            let errMsg = "";
            (val[0] as unknown[]).forEach(item => {
                if (typeof item != "string") {
                    errMsg = `属性${item}不是字符串`;
                } else {
                    if (!["call-chain", "loop", "method-call", "recover", "immediate-recover", "return"].includes(item)) {
                        errMsg = `非法属性${item}`;
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "dot-imports",
        name: "使用.导入包检查",
        descCn: "使用.导入包，使程序更加难以理解，因为它不清楚名称是属于当前包还是属于导入的。",
        descEn: "Importing with . makes the programs much harder to understand because it is unclear whether names belong to the current package or to an imported package.",
    },
    {
        id: "duplicated-imports",
        name: "重复导入包检查",
        descCn: "可能会无意中导入同一个包两次。该规则查找导入两次或两次以上的包。",
        descEn: "It is possible to unintentionally import the same package twice. This rule looks for packages that are imported two or more times.",
    },
    {
        id: "early-return",
        name: "提前返回检查",
        descCn: "在Go中，最小化嵌套语句是惯用的，一个典型的例子是避免if-then-else结构。",
        descEn: "In Go it is idiomatic to minimize nesting statements, a typical example is to avoid if-then-else constructions. ",
    },
    {
        id: "empty-block",
        name: "空块检查",
        descCn: "空块使代码可读性较差，可能是错误或未完成重构的症状。",
        descEn: "Empty blocks make code less readable and could be a symptom of a bug or unfinished refactoring.",
    },
    {
        id: "empty-lines",
        name: "空白行检查",
        descCn: "有时gofmt不足以强制代码库的通用格式;当代码块中有标题或末尾换行符时，该规则会发出警告。",
        descEn: "Sometimes gofmt is not enough to enforce a common formatting of a code-base; this rule warns when there are heading or trailing newlines in code blocks.",
    },
    {
        id: "error-naming",
        name: "错误命名检查",
        descCn: "按照惯例，为了可读性，类型错误的变量必须以err前缀命名。",
        descEn: "By convention, for the sake of readability, variables of type error must be named with the prefix err.",
    },
    {
        id: "error-return",
        name: "错误返回检查",
        descCn: "按照惯例，为了可读性，错误应该放在函数返回值列表的最后。",
        descEn: "By convention, for the sake of readability, the errors should be last in the list of returned values by a function.",
    },
    {
        id: "error-strings",
        name: "错误字符串检查",
        descCn: "按照惯例，为了更好的可读性，错误消息不应该大写或以标点符号或换行符结束。",
        descEn: "By convention, for better readability, error messages should not be capitalized or end with punctuation or a newline.",
    },
    {
        id: "errorf",
        name: "errof调用检查",
        descCn: "可以通过将errors.New(fmt.Sprintf())替换为fmt.Errorf()来获得一个更简单的程序。这个规则发现了这种简化的机会。",
        descEn: "It is possible to get a simpler program by replacing errors.New(fmt.Sprintf()) with fmt.Errorf(). This rule spots that kind of simplification opportunities.",
    },
    {
        id: "exported",
        name: "导出函数检查",
        descCn: "导出的函数和方法应该有注释。这将对未记录的导出函数和方法发出警告。",
        descEn: "Exported function and methods should have comments. This warns on undocumented exported functions and methods.",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: `规则标记
checkPrivateReceivers 启用检查私有类型的公共方法
disableStutteringCheck 禁止检查与包名结巴的方法名(即避免表单类型名称的失败消息将被其他包用作x.XY，并且结巴;可以把这个叫做Y)
sayRepetitiveInsteadOfStutters 通过在失败消息中重复替换术语口吃的使用`,
                descEn: `rule flags:
checkPrivateReceivers enables checking public methods of private types   
disableStutteringCheck disables checking for method names that stutter with the package name (i.e. avoid failure messages of the form type name will be used as x.XY by other packages, and that stutters; consider calling this Y)
sayRepetitiveInsteadOfStutters replaces the use of the term stutters by repetitive in failure messages             
                `,
            }
        ],
        demoValue: ["checkPrivateReceivers", "disableStutteringCheck"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组不能为空";
            }
            let errMsg = "";
            val.forEach(item => {
                if (typeof item != "string") {
                    errMsg = "数组元素必须是字符串";
                } else {
                    if (!["checkPrivateReceivers", "disableStutteringCheck", "sayRepetitiveInsteadOfStutters"].includes(item)) {
                        errMsg = `非法属性${item}`;
                    }
                }
            })
            return errMsg;
        },
    },
    {
        id: "file-header",
        name: "文件头检查",
        descCn: "该规则通过发现那些没有指定头的文件，有助于为项目中的所有源文件强制使用一个公共头。",
        descEn: "This rule helps to enforce a common header for all source files in a project by spotting those files that do not have the specified header.",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: "要在源文件中查找的头。",
                descEn: "the header to look for in source files.",
            },
        ],
        demoValue: ["This is the text that must appear at the top of source files."],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个字符串元素";
            } else {
                if (typeof val[0] != "string") {
                    return "元素必须是字符串";
                } else {
                    if (val[0].trim() == "") {
                        return "元素不能是空字符串";
                    }
                }
            }
            return "";
        },
    },
    {
        id: "flag-parameter",
        name: "标记参数检查",
        descCn: "如果一个函数通过传递要做什么的信息来控制另一个函数的流，那么两个函数都是控制耦合的。为了更好的代码可维护性，函数之间的耦合必须最小化。该规则对创建控件耦合的布尔参数发出警告。",
        descEn: "If a function controls the flow of another by passing it information on what to do, both functions are said to be control-coupled. Coupling among functions must be minimized for better maintainability of the code. This rule warns on boolean parameters that create a control coupling.",
    },
    {
        id: "function-result-limit",
        name: "函数返回数量检查",
        descCn: "返回太多结果的函数可能很难理解/使用。",
        descEn: "Functions returning too many results can be hard to understand/use.",
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "允许的最大返回值",
                descEn: "the maximum allowed return values",
            },
        ],
        demoValue: [3],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 2) {
                    return "数值不能小于2";
                }
            }
            return "";
        },
    },
    {
        id: "function-length",
        name: "函数长度检查",
        descCn: "函数太长(包含许多语句和/或行)可能难以理解。",
        descEn: "Functions too long (with many statements and/or lines) can be hard to understand.",
        paramList: [
            {
                id: "",
                paramType: "整数数组(2个值)",
                descCn: "允许的语句和行数的最大值。必须是非负整数。0表示不检查",
                descEn: "the maximum allowed statements and lines. Must be non-negative integers. Set to 0 to disable the check",
            },
        ],
        demoValue: [10, 0],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 2) {
                return "数组中只能包含两个整数元素";
            } else {
                if (!Number.isInteger(val[0]) || !Number.isInteger(val[1])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) < 0 || (val[1] as number) < 0) {
                    return "数值不能小于0";
                }
            }
            return "";
        },
    },
    {
        id: "get-return",
        name: "get前缀函数检查",
        descCn: "通常，带有Get前缀的函数应该返回一个值。",
        descEn: "Typically, functions with names prefixed with Get are supposed to return a value.",
    },
    {
        id: "identical-branches",
        name: "相同分支检查",
        descCn: "在两个分支中具有相同实现的If-then-else条件是错误的。",
        descEn: "if-then-else conditional with identical implementations in both branches is an error.",
    },
    {
        id: "if-return",
        name: "if返回检查",
        descCn: "在返回错误之后检查一个错误是否为nil或nil是多余的。",
        descEn: "Checking if an error is nil to just after return the error or nil is redundant.",
    },
    {
        id: "increment-decrement",
        name: "自增自减格式检查",
        descCn: "按照惯例，为了更好的可读性，建议使用++操作符对整数变量加1。该规则发现像i+ = 1和i- = 1这样的表达式，并建议将它们更改为i++和i——。",
        descEn: "By convention, for better readability, incrementing an integer variable by 1 is recommended to be done using the ++ operator. This rule spots expressions like i += 1 and i -= 1 and proposes to change them into i++ and i--.",
    },
    {
        id: "indent-error-flow",
        name: "流程精简检查",
        descCn: "为了提高代码的可读性，建议尽量减少缩进。该规则突出显示了可以从代码中消除的冗余else块。",
        descEn: "To improve the readability of code, it is recommended to reduce the indentation as much as possible. This rule highlights redundant else-blocks that can be eliminated from the code.",
    },
    {
        id: "imports-blacklist",
        name: "黑名单包检查",
        descCn: "导入黑名单包时发出警告。",
        descEn: "Warns when importing black-listed packages.",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: "包名(或正则表达式包名)的黑名单。",
                descEn: "black-list of package names (or regular expression package names).",
            },
        ],
        demoValue: ["crypto/md5", "crypto/sha1", "crypto/**/pkix"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组不能为空";
            }
            let errMsg = "";
            val.forEach(item => {
                if (typeof item != "string") {
                    errMsg = "元素必须是字符串";
                } else {
                    if (item.trim() == "") {
                        errMsg = "元素不能是空字符串";
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "import-shadowing",
        name: "导入隐藏检查",
        descCn: "在GO中，可以声明与导入包的名称冲突的标识符(包、结构、接口、参数、接收器、变量、常量……)。该规则发现隐藏在导入后面的标识符。",
        descEn: "In GO it is possible to declare identifiers (packages, structs, interfaces, parameters, receivers, variables, constants...) that conflict with the name of an imported package. This rule spots identifiers that shadow an import.",
    },
    {
        id: "line-length-limit",
        name: "代码行长度检查",
        descCn: "如果代码行长度超过配置的最大值，则发出警告。",
        descEn: "Warns in the presence of code lines longer than a configured maximum.",
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "单行最多字符数。",
                descEn: "maximum line length in characters.",
            },
        ],
        demoValue: [80],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 20) {
                    return "数值不能小于20";
                }
            }
            return "";
        },
    },
    {
        id: "max-public-structs",
        name: "公共结构数量检查",
        descCn: "声明太多公共结构的包可能很难理解/使用，并且可能是糟糕设计的症状。",
        descEn: "Packages declaring too many public structs can be hard to understand/use, and could be a symptom of bad design.",
        paramList: [
            {
                id: "",
                paramType: "整数",
                descCn: "单个包内的最大公共结构体数量。",
                descEn: "the maximum allowed public structs",
            },
        ],
        demoValue: [3],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length != 1) {
                return "数组中只能包含一个整数元素";
            } else {
                if (!Number.isInteger(val[0])) {
                    return "只能配置整数元素";
                }
                if ((val[0] as number) <= 2) {
                    return "数值不能小于2";
                }
            }
            return "";
        },
    },
    {
        id: "modifies-parameter",
        name: "参数修改检查",
        descCn: "修改参数的函数可能很难理解。如果参数由调用者按值传递，也会产生误导。该规则在函数修改一个或多个参数时发出警告。",
        descEn: "A function that modifies its parameters can be hard to understand. It can also be misleading if the arguments are passed by value by the caller. This rule warns when a function modifies one or more of its parameters.",
    },
    {
        id: "modifies-value-receiver",
        name: "修改值接收者检查",
        descCn: "修改其接收方值的方法可能会产生不希望看到的行为。修改也可能是错误的根源，因为实际的值接收者可能是调用站点使用的值的副本。该规则在方法修改其接收者时发出警告。",
        descEn: "A method that modifies its receiver value can have undesired behavior. The modification can be also the root of a bug because the actual value receiver could be a copy of that used at the calling site. This rule warns when a method modifies its receiver.",
    },
    {
        id: "nested-structs",
        name: "内联结构检查",
        descCn: "声明包含其他内联结构定义的结构的包对于其他开发人员来说可能很难理解/阅读。",
        descEn: "Packages declaring structs that contain other inline struct definitions can be hard to understand/read for other developers.",
    },
    {
        id: "optimize-operands-order",
        name: "优化计算顺序检查",
        descCn: "可以编写条件表达式来利用短路求值，并通过强制在耗时较短的项之前求值来加快其平均求值时间。该规则指出了那些项的求值顺序似乎不是最优的逻辑表达式。请注意，该规则的置信度很低，由用户决定建议的表达式重写是否保持原始表达式的语义。",
        descEn: "conditional expressions can be written to take advantage of short circuit evaluation and speed up its average evaluation time by forcing the evaluation of less time-consuming terms before more costly ones. This rule spots logical expressions where the order of evaluation of terms seems non optimal. Please notice that confidence of this rule is low and is up to the user to decide if the suggested rewrite of the expression keeps the semantics of the original one.",
    },
    {
        id: "package-comments",
        name: "包注释检查",
        descCn: "包应该有注释。该规则警告未记录的包，以及当包注释被分离到package关键字时",
        descEn: "Packages should have comments. This rule warns on undocumented packages and when packages comments are detached to the package keyword.",
    },
    {
        id: "range",
        name: "简化range检查",
        descCn: "该规则建议使用一种不使用第二个值的更短的方式来写入范围。",
        descEn: "This rule suggests a shorter way of writing ranges that do not use the second value.",
    },
    {
        id: "range-val-in-closure",
        name: "闭包中使用range检查",
        descCn: "循环中的范围变量在每次迭代中都被重用;因此，在循环中创建的goroutine将指向来自上层作用域的range变量。这样，goroutine就可以使用带有不需要的值的变量。该规则在闭包中使用范围值(或索引)时发出警告",
        descEn: "Range variables in a loop are reused at each iteration; therefore a goroutine created in a loop will point to the range variable with from the upper scope. This way, the goroutine could use the variable with an undesired value. This rule warns when a range value (or index) is used inside a closure",
    },
    {
        id: "range-val-address",
        name: "通过地址range检查",
        descCn: "循环中的范围变量在每次迭代中都被重用。该规则在为变量分配地址、将地址传递给append()或在映射中使用它时发出警告。",
        descEn: "Range variables in a loop are reused at each iteration. This rule warns when assigning the address of the variable, passing the address to append() or using it in a map.",
    },
    {
        id: "receiver-naming",
        name: "方法接收者命名检查",
        descCn: "按照惯例，方法中的接收方名称应该反映它们的身份。例如，如果接收者的类型是Parts，那么p就是一个合适的名称。与其他语言相反，将接收者命名为this或self是不习惯的。",
        descEn: "By convention, receiver names in a method should reflect their identity. For example, if the receiver is of type Parts, p is an adequate name for it. Contrary to other languages, it is not idiomatic to name receivers as this or self.",
    },
    {
        id: "redefines-builtin-id",
        name: "内置名称重定义检查",
        descCn: "常量名称，如false, true, nil，函数名称，如append, make，以及基本类型名称，如bool和byte，都不是语言的保留字;因此，可以重新定义。即使可能，重新定义这些内置名称也会导致很难检测到的错误。",
        descEn: "Constant names like false, true, nil, function names like append, make, and basic type names like bool, and byte are not reserved words of the language; therefore the can be redefined. Even if possible, redefining these built in names can lead to bugs very difficult to detect.",
    },
    {
        id: "string-format",
        name: "字符串格式检查",
        descCn: "该规则允许您配置正则表达式列表，用于检查某些函数调用中的字符串字面值。这适用于面向用户的应用程序，其中字符串字面值通常用于将呈现给用户的消息，因此可能需要强制执行一致的格式。",
        descEn: "This rule allows you to configure a list of regular expressions that string literals in certain function calls are checked against. This is geared towards user facing applications where string literals are often used for messages that will be presented to users, so it may be desirable to enforce consistent formatting.",
        paramList: [
            {
                id: "",
                paramType: "字符串数组(2-3个值)",
                descCn: `第一个字符串定义了一个作用域。
第二个字符串是一个正则表达式(以/字符开头和结尾)，它将用于检查作用域中的字符串字面量。
第三个字符串(可选)是一个包含正则表达式目的的消息，它将用于lint错误。`,
                descEn: `The first string defines a scope.
The second string is a regular expression (beginning and ending with a / character), which will be used to check the string literals in the scope.
The third string (optional) is a message containing the purpose for the regex, which will be used in lint errors.
                `,
            }
        ],
        demoValue: [
            ["core.WriteError[1].Message", "/^([^A-Z]|$)/", "must not start with a capital letter"],
            ["fmt.Errorf[0]", "/(^|[^\\.!?])$/", "must not end in punctuation"],
            ["panic", "/^[^\\n]*$/", "must not contain line breaks"]],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组中至少包含一条规则";
            }
            let errMsg = "";
            val.forEach(item => {
                if (!Array.isArray(item)) {
                    errMsg = "元素必须是数组";
                } else {
                    if (item.length < 2 || item.length > 3) {
                        errMsg = "元素数组长度必须是2或3";
                    } else {
                        item.forEach(subItem => {
                            if (typeof subItem != "string") {
                                errMsg = `${subItem}不是字符串`;
                            }
                        })
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "struct-tag",
        name: "结构标签检查",
        descCn: "在编译时不检查结构标记。该规则检查并警告在常见的结构标签类型如:asn1, default, json, protobuf, xml, yaml中发现错误。",
        descEn: "Struct tags are not checked at compile time. This rule, checks and warns if it finds errors in common struct tags types like: asn1, default, json, protobuf, xml, yaml.",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: "用户定义的选项列表。",
                descEn: "list of user defined options.",
            }
        ],
        demoValue: ["json,inline", "bson,outline,gnu"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if (val.length == 0) {
                return "数组不能为空";
            }
            let errMsg = ""
            val.forEach(item => {
                if (typeof item != "string") {
                    errMsg = "元素必须是字符串";
                } else {
                    if (item.trim() == "") {
                        errMsg = "元素不能是空字符串";
                    }
                }
            })
            return errMsg;
        },
    },
    {
        id: "superfluous-else",
        name: "消除else块检查",
        descCn: "为了提高代码的可读性，建议尽量减少缩进。该规则突出显示了可以从代码中消除的冗余else块。",
        descEn: "To improve the readability of code, it is recommended to reduce the indentation as much as possible. This rule highlights redundant else-blocks that can be eliminated from the code.",
    },
    {
        id: "time-equal",
        name: "时间相等检查",
        descCn: "当使用==和!=进行时间相等性检查时，该规则会发出警告。建议使用time.time.Equal方法",
        descEn: "This rule warns when using == and != for equality check time.Time and suggest to time.time.Equal method",
    },
    {
        id: "time-naming",
        name: "时间命名检查",
        descCn: "使用特定于单位的后缀，如“Secs”，“Mins”，…当命名类型为time的变量时。time.Duration可能会误导人，这条规则强调了这些情况。",
        descEn: `Using unit-specific suffix like "Secs", "Mins", ... when naming variables of type time.Duration can be misleading, this rule highlights those cases.`,
    },
    {
        id: "var-naming",
        name: "变量命名检查",
        descCn: "当不遵循首字母、变量或包的命名约定时，该规则会发出警告。",
        descEn: "This rule warns when initialism, variable or package naming conventions are not followed.",
        paramList: [
            {
                id: "",
                paramType: "字符串数组(1个值)",
                descCn: "该规则接受两个字符串片段，一个是白名单，一个是首字母的黑名单。",
                descEn: "This rule accepts two slices of strings, a whitelist and a blacklist of initialisms. ",
            }
        ],
        demoValue: [["ID"], ["VM"]],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if(val.length != 2){
                return "数组中必须包含两个数组元素";
            }
            if(!Array.isArray(val[0])){
                return "白名单必须是一个数组";
            }
            if(!Array.isArray(val[1])){
                return "黑名单必须是一个数组";
            }
            let errMsg = "";
            val[0].forEach(item=>{
                if(typeof item != "string"){
                    errMsg = "白名单元素必须是字符串";
                }else{
                    if(item.trim() == ""){
                        errMsg = "白名单字符串必能为空";
                    }
                }
            });
            val[1].forEach(item=>{
                if(typeof item != "string"){
                    errMsg = "黑名单元素必须是字符串";
                }else{
                    if(item.trim() == ""){
                        errMsg = "黑名单字符串必能为空";
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "var-declaration",
        name: "变量申明简化检查",
        descCn: "该规则建议简化变量声明。",
        descEn: "This rule proposes simplifications of variable declarations.",
    },
    {
        id: "unconditional-recursion",
        name: "无条件递归检查",
        descCn: "无条件递归调用将产生无限递归，从而导致程序堆栈溢出。该规则检测并警告无条件(直接)递归调用。",
        descEn: "Unconditional recursive calls will produce infinite recursion, thus program stack overflow. This rule detects and warns about unconditional (direct) recursive calls.",
    },
    {
        id: "unexported-naming",
        name: "未导出命名检查",
        descCn: "该规则对错误命名的未导出符号发出警告，即名称以大写字母开头的未导出符号。",
        descEn: "this rule warns on wrongly named un-exported symbols, i.e. un-exported symbols whose name start with a capital letter.",
    },
    {
        id: "unexported-return",
        name: "未导出返回类型检查",
        descCn: "当导出的函数或方法返回未导出类型的值时，该规则发出警告。",
        descEn: "This rule warns when an exported function or method returns a value of an un-exported type.",
    },
    {
        id: "unhandled-error",
        name: "未处理错误检查",
        descCn: "当调用方没有显式地处理函数返回的错误时，该规则会发出警告。",
        descEn: "This rule warns when errors returned by a function are not explicitly handled on the caller side.",
        paramList: [
            {
                id: "",
                paramType: "字符串",
                descCn: "要忽略的函数名(支持正则表达式)",
                descEn: "function names regexp patterns to ignore",
            }
        ],
        demoValue: ["os\.(Create|WriteFile|Chmod)", "fmt\.Print", "myFunction", "net\..*", "bytes\.Buffer\.Write"],
        checkParam: (val: unknown[]): string => {
            if (!Array.isArray(val)) {
                return "参数配置必须是一个数组";
            }
            if(val.length == 0){
                return "数组中至少包含一条规则";
            }
            let errMsg = "";
            val.forEach(item => {
                if(typeof item != "string"){
                    errMsg = "元素必须是字符串";
                }else{
                    if(item.trim() == ""){
                        errMsg = "元素不能是空字符串";
                    }
                }
            });
            return errMsg;
        },
    },
    {
        id: "unnecessary-stmt",
        name: "多余语句检查",
        descCn: "该规则建议删除冗余语句，例如case块末尾的break，以提高代码的可读性。",
        descEn: "This rule suggests to remove redundant statements like a break at the end of a case block, for improving the code's readability.",
    },
    {
        id: "unreachable-code",
        name: "不可到达代码检查",
        descCn: "该规则发现并建议删除不可访问的代码。",
        descEn: "This rule spots and proposes to remove unreachable code.",
    },
    {
        id: "unused-parameter",
        name: "未使用参数检查",
        descCn: "该规则对未使用的参数发出警告。带有未使用参数的函数或方法可能是未完成重构或错误的症状。",
        descEn: "This rule warns on unused parameters. Functions or methods with unused parameters can be a symptom of an unfinished refactoring or a bug.",
    },
    {
        id: "unused-receiver",
        name: "未使用接收器检查",
        descCn: "该规则对未使用的方法接收器发出警告。带有未使用接收器的方法可能是未完成的重构或错误的症状。",
        descEn: "This rule warns on unused method receivers. Methods with unused receivers can be a symptom of an unfinished refactoring or a bug.",
    },
    {
        id: "use-any",
        name: "any使用提示检查",
        descCn: "从GO 1.18开始，interface{}有一个别名:any。该规则建议将interface{}的实例替换为any。",
        descEn: "Since GO 1.18, interface{} has an alias: any. This rule proposes to replace instances of interface{} with any.",
    },
    {
        id: "useless-break",
        name: "多余break检查",
        descCn: "该规则警告switch和select语句的case子句中无用的break语句。GO与C等其他编程语言不同，它只执行所选case的语句，而忽略后续的case子句。因此，在case子句的末尾插入break没有效果。",
        descEn: "This rule warns on useless break statements in case clauses of switch and select statements. GO, unlike other programming languages like C, only executes statements of the selected case while ignoring the subsequent case clauses. Therefore, inserting a break at the end of a case clause has no effect.",
    },
    {
        id: "waitgroup-by-value",
        name: "WaitGroup传值检查",
        descCn: "按值传递的函数形参实际上是原始实参的副本。传递一个同步的副本。WaitGroup通常不是开发人员想要做的。该规则在同步时发出警告。WaitGroup期望作为函数或方法中的值参数。",
        descEn: "Function parameters that are passed by value, are in fact a copy of the original argument. Passing a copy of a sync.WaitGroup is usually not what the developer wants to do. This rule warns when a sync.WaitGroup expected as a by-value parameter in a function or method.",
    }
];

